package com.factory.code.lib.database.biz.h2;


import com.factory.code.lib.database.DatabaseBehavior;
import com.factory.code.lib.database.model.TableColumnModel;
import com.factory.code.lib.database.model.TableInfoModel;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


/**
 * mysql database service implement
 *
 * @author yinyansheng
 */
@Component
@Scope("prototype")
class H2DatabaseBehavior extends DatabaseBehavior {

    private static final String SCHEME_SQL = "SELECT database()";

    private static final String TABLE_SQL = "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES " +
            "WHERE TABLE_CATALOG=?";

    private static final String COLUMN_SQL = "SELECT * FROM INFORMATION_SCHEMA.COLUMNS " +
            "WHERE TABLE_CATALOG=? AND TABLE_NAME=? ORDER BY ORDINAL_POSITION";

    private static final String PRIMARY_KEY_SQL = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.INDEXES " +
            "WHERE TABLE_CATALOG=? AND TABLE_NAME=? AND PRIMARY_KEY='TRUE'";

    @Override
    public String getDbType() {
        return "h2";
    }

    @Override
    public List<String> getDbDriver() {
        List<String> list = new ArrayList<>();
        list.add("org.h2.Driver");
        return list;
    }

    @Override
    public String getDatabaseName() {
        String schema = getJdbcTemplate().queryForObject(SCHEME_SQL, String.class);
        if (StringUtils.isEmpty(schema)) {
            throw new IllegalArgumentException("get schema failure");
        }
        return schema;
    }

    @Override
    public List<String> listTableName() {
        String schema = getDatabaseName();
        return getJdbcTemplate().queryForList(TABLE_SQL, String.class, schema);
    }

    @Override
    public List<TableInfoModel> getTableAll() {
        String schema = getDatabaseName();
        List<TableInfoModel> tableModelList = getJdbcTemplate().query(TABLE_SQL, new BeanPropertyRowMapper<>(TableInfoModel.class), schema);
        return tableModelList;
    }

    public Set<String> getPrimaryKeySet(String tableName) {
        String schema = getDatabaseName();
        return new HashSet<>(getJdbcTemplate().queryForList(PRIMARY_KEY_SQL, String.class, schema, tableName));
    }

    @Override
    public List<TableColumnModel> listFieldModel(String tableName) {
        String schema = getDatabaseName();
//        Set<String> primaryKeySet = getPrimaryKeySet(tableName);
        List<H2ColumnModel> columnModelList = getJdbcTemplate().query(COLUMN_SQL, new BeanPropertyRowMapper<>(H2ColumnModel.class), schema, tableName);
        List<TableColumnModel> list = new ArrayList<>();

        Set<String> primaryKeySet = getPrimaryKeySet(tableName);
        for (H2ColumnModel h2ColumnModel : columnModelList) {
            TableColumnModel model = new TableColumnModel();
            model.setColumnName(h2ColumnModel.getColumnName());
            model.setComment(h2ColumnModel.getRemarks());
            model.setIsPk(primaryKeySet.contains(h2ColumnModel.getColumnName()));
            model.setDataType(h2ColumnModel.getDataType());
//            model.setMaxLength();
            list.add(model);
        }
        return list;

    }

    @Override
    public String getDbAttrType(String dbType) {
        return null;
    }


}
